package com.haojiang.mh.widget;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import androidx.annotation.Keep;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.utils.ImageUtil;

/**
 * Created by Will on 2017/9/12 10:42.
 * <p>
 * wuzhuang@mirahome.me
 */
public class SearchDeviceView extends View {

    private Bitmap upBitmap, midBitmap, botBitmap;
    private int width, height, defaultWidth, defaultHeight;
    private ObjectAnimator animator;
    private float mAngle;
    private Matrix matrix;

    public SearchDeviceView(Context context) {
        this(context, null);
    }

    public SearchDeviceView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SearchDeviceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        upBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.img_search_anim_up);
        midBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.img_search_anim_mid);
        botBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.img_search_anim_bot);
        defaultWidth = botBitmap.getWidth();
        defaultHeight = botBitmap.getHeight();

        animator = ObjectAnimator.ofFloat(this, "angle", 0.0f, 1.0f);
        animator.setDuration(1500);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);

        matrix = new Matrix();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        botBitmap = createEqualBitmap(botBitmap);
        midBitmap = createEqualBitmap(midBitmap);
        upBitmap = createEqualBitmap(upBitmap);
        canvas.drawBitmap(botBitmap, width * 0.5f - botBitmap.getWidth() * 0.5f, height * 0.5f - botBitmap.getHeight() * 0.5f, null);
        canvas.save();
        canvas.rotate(360f * mAngle, width * 0.5f, height * 0.5f);
        canvas.drawBitmap(midBitmap, width * 0.5f - midBitmap.getWidth() * 0.5f, height * 0.5f - midBitmap.getHeight() * 0.5f, null);
        canvas.restore();
        canvas.drawBitmap(upBitmap, width * 0.5f - upBitmap.getWidth() * 0.5f, height * 0.5f - upBitmap.getHeight() * 0.5f, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    private Bitmap createEqualBitmap(Bitmap bitmap) {
        if (bitmap == null) return null;
        if (bitmap.getWidth() <= width && bitmap.getHeight() <= height) return bitmap;
        int size = Math.min(width, height);
        matrix.reset();
        matrix.postScale((float) size / bitmap.getWidth(), (float) size / bitmap.getHeight());
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
    }

    @Keep
    public void setAngle(float angle) {
        this.mAngle = angle;
        postInvalidate();
    }

    public void stop() {
        if (animator != null) {
            if (animator.isRunning()) {
                animator.cancel();
            }
            animator = null;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (animator != null && !animator.isRunning()) {
            animator.start();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (animator != null) {
            if (animator.isRunning()) {
                animator.cancel();
            }
            animator = null;
            System.gc();
        }
        super.onDetachedFromWindow();
    }
}
